#include "StdAfx.h"
#include "HouseSort.h"
#include <boost/lexical_cast.hpp>

using namespace boost;


bool HouseSort::operator()(const House& house1, const House& house2)
{
    bool bResult = false;

    switch(m_bSortType)
    {
        case SORT_TYPE_SN:
            bResult = sortBySn(house1, house2);
            break;
        case SORT_TYPE_NUM:
            bResult = sortByNum(house1, house2);
            break;
        case SORT_TYPE_STRSTATUS:
            bResult = sortByStatus(house1, house2);
            break;
        case SORT_TYPE_UNITPRICE:
            bResult = sortByUnixPrice(house1, house2);
            break;
        case SORT_TYPE_SIZETOTAL:
            bResult = sortBySizeTotal(house1, house2);
            break;
        case SORT_TYPE_SIZESELF:
            bResult = sortBySizeSelf(house1, house2);
            break;
        case SORT_TYPE_SIZESHARE:
            bResult = sortBySizeShare(house1, house2);
            break;
        case SORT_TYPE_TOTALPRICE:
            bResult = sortByTotalPrice(house1, house2);
            break;
        default:
            break;
    }

    return bResult;
}

bool HouseSort::sortBySn(const House& house1, const House& house2)
{
    return m_bAsc ? house1.uiSN < house2.uiSN : house1.uiSN > house2.uiSN;
}

bool HouseSort::sortByNum(const House& house1, const House& house2)
{
    return m_bAsc ? house1.strNum < house2.strNum : house1.strNum > house2.strNum;
}

bool HouseSort::sortByStatus(const House& house1, const House& house2)
{
    return m_bAsc ? house1.strStatus < house2.strStatus : house1.strStatus > house2.strStatus;
}

bool HouseSort::sortByUnixPrice(const House& house1, const House& house2)
{
    float price1 = 0.0f;
    float price2 = 0.0f;
    bool isValid1 = true;
    bool isValid2 = true;
    bool bResult = false;

    try
    {
        price1 = boost::lexical_cast<float>(house1.strUnitPrice);
        isValid1 = true;
    }
    catch(const bad_lexical_cast&)
    {  
        isValid1 = false;
    } 

    try
    {
        price2 = boost::lexical_cast<float>(house2.strUnitPrice);
        isValid2 = true;
    }
    catch(const bad_lexical_cast&)
    {  
        isValid2 = false;
    }
    
    if ((true == isValid1) && (true == isValid2))
    {
        if ((int)(100 * price1) != (int)(100 * price2))
        {
            bResult = price1 < price2;
        }
        else
        {
            bResult = house1.uiSN < house2.uiSN;
        }
    }
    else if (true == isValid1)
    {
        bResult = true;
    }
    else if (true == isValid2)
    {
        bResult = false;
    }
    else
    {
        bResult = house1.uiSN < house2.uiSN;
    }

    return m_bAsc ? bResult : !bResult;
}

bool HouseSort::sortBySizeTotal(const House& house1, const House& house2)
{
    float price1 = boost::lexical_cast<float>(house1.strSizeTotal);
    float price2 = boost::lexical_cast<float>(house2.strSizeTotal);

    return m_bAsc ? price1 < price2 : price1 > price2;
}

bool HouseSort::sortBySizeSelf(const House& house1, const House& house2)
{
    float price1 = boost::lexical_cast<float>(house1.strSizeSelf);
    float price2 = boost::lexical_cast<float>(house2.strSizeSelf);

    return m_bAsc ? price1 < price2 : price1 > price2;
}

bool HouseSort::sortBySizeShare(const House& house1, const House& house2)
{
    float price1 = boost::lexical_cast<float>(house1.strSizeShare);
    float price2 = boost::lexical_cast<float>(house2.strSizeShare);

    return m_bAsc ? price1 < price2 : price1 > price2;
}


bool HouseSort::sortByTotalPrice(const House& house1, const House& house2)
{
    float price1 = 0.0f;
    float price2 = 0.0f;
    bool isValid1 = true;
    bool isValid2 = true;
    bool bResult = false;

    try
    {
        price1 = boost::lexical_cast<float>(house1.strUnitPrice) * boost::lexical_cast<float>(house1.strSizeTotal);
        isValid1 = true;
    }
    catch(const bad_lexical_cast&)
    {  
        isValid1 = false;
    } 

    try
    {
        price2 = boost::lexical_cast<float>(house2.strUnitPrice) * boost::lexical_cast<float>(house2.strSizeTotal);
        isValid2 = true;
    }
    catch(const bad_lexical_cast&)
    {  
        isValid2 = false;
    }

    if ((true == isValid1) && (true == isValid2))
    {
        if ((int)(100 * price1) != (int)(100 * price2))
        {
            bResult = price1 < price2;
        }
        else
        {
            bResult = house1.uiSN < house2.uiSN;
        }
    }
    else if (true == isValid1)
    {
        bResult = true;
    }
    else if (true == isValid2)
    {
        bResult = false;
    }
    else
    {
        bResult = house1.uiSN < house2.uiSN;
    }

    return m_bAsc ? bResult : !bResult;
}